//
//  Mg_image_lib.h
//  V3d_Cocoa
//
//  Created by yang liang on 11-3-23.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "v3d_ipadAppDelegate.h"
#import	"tiffio.h"

#define GREY   1   // 1-byte grey-level image or stack
#define GREY16 2   // 2-byte grey-level image or stack
#define COLOR  3   // 3-byte RGB image or stack

#define GREY_CHANNEL  0   // Images and stacks either have a single grey channel or 3 color channels
#define RED_CHANNEL   0
#define GREEN_CHANNEL 1
#define BLUE_CHANNEL  2

typedef struct
{	int      kind;
    int      width; 
    int      height;
    uint8   *array;   // Array of pixel values lexicographically ordered on (y,x,c).
} Image;

#define IMAGE_PIXEL_8(img,x,y,c) \
((uint8  *) ((img)->array + (((y)*(img)->width + (x))*(img)->kind + (c))))

#define IMAGE_PIXEL_16(img,x,y,c) \
((uint16 *) ((img)->array + (((y)*(img)->width + (x))*(img)->kind + (c))))

static inline int Get_Image_Pixel(Image *image, int x, int y, int c)
{	if (image->kind == GREY16)
		return (*IMAGE_PIXEL_16(image,x,y,c));
	else
		return (*IMAGE_PIXEL_8(image,x,y,c));
}

static inline void Set_Image_Pixel(Image *image, int x, int y, int c, int v)
{	if (image->kind == GREY16)
		*IMAGE_PIXEL_16(image,x,y,c) = v;
	else
		*IMAGE_PIXEL_8(image,x,y,c) = v;
}

TIFF   *Open_Tiff(const char *file_name, char *mode);


/* STACK ABSTRACTION */

typedef struct
{	int      kind;
    int      width;
    int      height;
    int      depth;
    uint8   *array;   // array of pixel values lexicographically ordered on (z,y,x,c)
} Stack;

#define STACK_PIXEL_8(img,x,y,z,c) \
((uint8  *) ((img)->array +   \
((((z)*(img)->height + (y))*(img)->width + (x))*(img)->kind + (c))))

#define STACK_PIXEL_16(img,x,y,z,c) \
((uint16 *) ((img)->array +   \
((((z)*(img)->height + (y))*(img)->width + (x))*(img)->kind + (c))))

static inline int Get_Stack_Pixel(Stack *stack, int x, int y, int z, int c)
{	if (stack->kind == GREY16)
		return (*STACK_PIXEL_16(stack,x,y,z,c));
	else
		return (*STACK_PIXEL_8(stack,x,y,z,c));
}

static inline void Set_Stack_Pixel(Stack *stack, int x, int y, int z, int c, int v)
{	if (stack->kind == GREY16)
		*STACK_PIXEL_16(stack,x,y,z,c) = v;
	else
		*STACK_PIXEL_8(stack,x,y,z,c) = v;
}

Stack *Read_Stack(const char *file_name);
void   Kill_Stack(Stack *stack);


typedef Image Stack_Plane;

Stack_Plane *Select_Plane(Stack *a_stack, int plane);

